#ifndef NEURALNET_H
#define NEURALNET_H

#include <vector>
#include "../misc/utils.h"

#define I_NUM_INPUTS				4
#define I_NUM_OUTPUTS				2
#define I_NUM_HIDDEN				1
#define I_NEURONS_PER_HIDDEN_LAYER	6
#define D_BIAS						-1
#define D_ACTIVATION_RESPONSE		1

using namespace std;

struct Neuron
{
	// number of inputs into the neuron
	int	m_iNumInputs;

	// the weights for each input
	vector<double> m_vecWeight;

	// ctor
	Neuron(int iNumInputs);
};


struct NeuronLayer
{
    // the number of neurons in the layer
    int m_iNumNeurons;
    
    // the layer of neurons
    vector<Neuron> m_vecNeurons;
    
    NeuronLayer(int iNumNeurons, int iNumInputsPerNeuron);
};

class NeuralNet
{
private:
    int		m_iNumInputs;

    int		m_iNumOutputs;

    int		m_iNumHiddenLayers;

	int		m_iNeuronsPerHiddenLyr;

    // storage for each layer of neurons including the output layer
    vector<NeuronLayer> m_vecLayers;

public:
    NeuralNet();

    void CreateNet();

    // gets the weights from the net
    vector<double> GetWeights()const;

    // replaces the weights with new ones
    void PutWeights(vector<double> &weights);

	//returns total number of weights in net
	int GetNumberOfWeights()const;

    // calculates the outputs from a set of inputs
    vector<double> Update(vector<double> &inputs);

    // sigmoid response curve
    inline double Sigmoid(double activation, double response);
};
	
#endif